enum Code {

    // **********************************************************
    // * Defined on the client side
    // **********************************************************

    // **********************************************************
    // * For application error
    // **********************************************************

    // Client - Common
    CONNECT_TIMEOUT = 1,

    DATA_NOT_FOUND = 10,

    HTTP_ERROR = 90,
    HTTP_NOT_SUCCESSFUL_RESPONSE,

    // Client - Request
    INVALID_REQUEST = 100,
    CLIENT_REQUESTS_TOO_FREQUENT,
    REQUEST_TIMEOUT,
    ILLEGAL_ARGUMENT,

    // Server - Notification
    INVALID_NOTIFICATION = 200,
    INVALID_RESPONSE,

    // **********************************************************
    // * For business error
    // **********************************************************

    // User
    CLIENT_SESSION_ALREADY_ESTABLISHED = 300,
    CLIENT_SESSION_HAS_BEEN_CLOSED,

    // Group

    // Conversation

    // Message

    // Storage

    // **********************************************************
    // * Defined on the server side
    // **********************************************************

    // Successful responses
    OK = 1000,
    NO_CONTENT,
    ALREADY_UP_TO_DATE,

    //**********************************************************
    //* For application error
    //**********************************************************

    // Client
    INVALID_REQUEST_FROM_SERVER = 1100,
    CLIENT_REQUESTS_TOO_FREQUENT_FROM_SERVER,
    ILLEGAL_ARGUMENT_FROM_SERVER,
    RECORD_CONTAINS_DUPLICATE_KEY,
    REQUESTED_RECORDS_TOO_MANY,
    SEND_REQUEST_FROM_NONEXISTENT_SESSION,
    UNAUTHORIZED_REQUEST,

    // Server
    SERVER_INTERNAL_ERROR = 1200,
    SERVER_UNAVAILABLE,

    // **********************************************************
    // * For business error
    // **********************************************************

    // User

    // User - Login
    UNSUPPORTED_CLIENT_VERSION = 2000,

    LOGIN_TIMEOUT = 2010,
    LOGIN_AUTHENTICATION_FAILED,
    LOGGING_IN_USER_NOT_ACTIVE,
    LOGIN_FROM_FORBIDDEN_DEVICE_TYPE,

    // User - Session
    SESSION_SIMULTANEOUS_CONFLICTS_DECLINE = 2100,
    SESSION_SIMULTANEOUS_CONFLICTS_NOTIFY,
    SESSION_SIMULTANEOUS_CONFLICTS_OFFLINE,
    CREATE_EXISTING_SESSION,
    UPDATE_HEARTBEAT_OF_NONEXISTENT_SESSION,

    // User - Location
    USER_LOCATION_RELATED_FEATURES_ARE_DISABLED = 2200,
    QUERYING_NEAREST_USERS_BY_SESSION_ID_IS_DISABLED,

    // User - Info
    UPDATE_INFO_OF_NONEXISTENT_USER = 2300,
    USER_PROFILE_NOT_FOUND,
    PROFILE_REQUESTER_NOT_IN_CONTACTS_OR_BLOCKED,
    PROFILE_REQUESTER_HAS_BEEN_BLOCKED,

    // User - Permission
    QUERY_PERMISSION_OF_NONEXISTENT_USER = 2400,

    // User - Relationship
    ADD_NON_RELATED_USER_TO_GROUP = 2500,
    CREATE_EXISTING_RELATIONSHIP,

    // User - Friend Request
    REQUESTER_NOT_FRIEND_REQUEST_RECIPIENT = 2600,
    CREATE_EXISTING_FRIEND_REQUEST,
    FRIEND_REQUEST_SENDER_HAS_BEEN_BLOCKED,

    // Group

    // Group - Info
    UPDATE_INFO_OF_NONEXISTENT_GROUP = 3000,
    NOT_GROUP_OWNER_TO_UPDATE_GROUP_INFO,
    NOT_GROUP_OWNER_OR_MANAGER_TO_UPDATE_GROUP_INFO,
    NOT_GROUP_MEMBER_TO_UPDATE_GROUP_INFO,

    // Group - Type
    NO_PERMISSION_TO_CREATE_GROUP_WITH_GROUP_TYPE = 3100,
    CREATE_GROUP_WITH_NONEXISTENT_GROUP_TYPE,

    // Group - Ownership
    NOT_ACTIVE_USER_TO_CREATE_GROUP = 3200,
    NOT_GROUP_OWNER_TO_TRANSFER_GROUP,
    NOT_GROUP_OWNER_TO_DELETE_GROUP,
    SUCCESSOR_NOT_GROUP_MEMBER,
    OWNER_QUITS_WITHOUT_SPECIFYING_SUCCESSOR,
    MAX_OWNED_GROUPS_REACHED,
    TRANSFER_NONEXISTENT_GROUP,

    // Group - Question
    NOT_GROUP_OWNER_OR_MANAGER_TO_CREATE_GROUP_QUESTION = 3300,
    NOT_GROUP_OWNER_OR_MANAGER_TO_DELETE_GROUP_QUESTION,
    NOT_GROUP_OWNER_OR_MANAGER_TO_UPDATE_GROUP_QUESTION,
    NOT_GROUP_OWNER_OR_MANAGER_TO_ACCESS_GROUP_QUESTION_ANSWER,
    CREATE_GROUP_QUESTION_FOR_INACTIVE_GROUP,
    CREATE_GROUP_QUESTION_FOR_GROUP_USING_JOIN_REQUEST,
    CREATE_GROUP_QUESTION_FOR_GROUP_USING_INVITATION,
    CREATE_GROUP_QUESTION_FOR_GROUP_USING_MEMBERSHIP_REQUEST,
    GROUP_QUESTION_ANSWERER_HAS_BEEN_BLOCKED,
    GROUP_MEMBER_ANSWER_GROUP_QUESTION,
    ANSWER_INACTIVE_GROUP_QUESTION,
    ANSWER_GROUP_QUESTION_OF_INACTIVE_GROUP,

    // Group - Member
    ADD_USER_TO_GROUP_REQUIRING_INVITATION = 3400,
    ADD_USER_TO_INACTIVE_GROUP,
    ADD_USER_TO_GROUP_WITH_ROLE_HIGHER_THAN_REQUESTER,
    ADD_USER_TO_GROUP_WITH_SIZE_LIMIT_REACHED,
    ADD_BLOCKED_USER_TO_GROUP,
    ADD_BLOCKED_USER_TO_INACTIVE_GROUP,
    NOT_GROUP_OWNER_OR_MANAGER_TO_REMOVE_GROUP_MEMBER,
    NOT_GROUP_OWNER_TO_REMOVE_GROUP_OWNER_OR_MANAGER,
    NOT_GROUP_OWNER_TO_UPDATE_GROUP_MEMBER_ROLE,
    UPDATE_GROUP_MEMBER_ROLE_OF_NONEXISTENT_GROUP,
    NOT_GROUP_OWNER_TO_UPDATE_GROUP_MEMBER_INFO,
    NOT_GROUP_OWNER_OR_MANAGER_TO_UPDATE_GROUP_MEMBER_INFO,
    NOT_GROUP_MEMBER_TO_UPDATE_GROUP_MEMBER_INFO,
    UPDATE_GROUP_MEMBER_INFO_OF_NONEXISTENT_GROUP,
    UPDATE_INFO_OF_NONEXISTENT_GROUP_MEMBER,
    NOT_GROUP_OWNER_OR_MANAGER_TO_MUTE_GROUP_MEMBER,
    MUTE_GROUP_MEMBER_WITH_ROLE_EQUAL_TO_OR_HIGHER_THAN_REQUESTER,
    MUTE_GROUP_MEMBER_OF_NONEXISTENT_GROUP,
    MUTE_NONEXISTENT_GROUP_MEMBER,
    NOT_GROUP_MEMBER_TO_QUERY_GROUP_MEMBER_INFO,

    // Group - Blocklist
    NOT_GROUP_OWNER_OR_MANAGER_TO_ADD_BLOCKED_USER = 3500,
    NOT_GROUP_OWNER_OR_MANAGER_TO_REMOVE_BLOCKED_USER,

    // Group - Join Request
    GROUP_JOIN_REQUEST_SENDER_HAS_BEEN_BLOCKED = 3600,
    NOT_GROUP_JOIN_REQUEST_SENDER_TO_RECALL_REQUEST,
    NOT_GROUP_OWNER_OR_MANAGER_TO_ACCESS_GROUP_JOIN_REQUEST,
    RECALL_NON_PENDING_GROUP_JOIN_REQUEST,
    SEND_GROUP_JOIN_REQUEST_TO_INACTIVE_GROUP,
    SEND_GROUP_JOIN_REQUEST_TO_GROUP_USING_MEMBERSHIP_REQUEST,
    SEND_GROUP_JOIN_REQUEST_TO_GROUP_USING_INVITATION,
    SEND_GROUP_JOIN_REQUEST_TO_GROUP_USING_QUESTION,
    RECALLING_GROUP_JOIN_REQUEST_IS_DISABLED,

    // Group - Invitation
    GROUP_INVITER_NOT_GROUP_MEMBER = 3700,
    GROUP_INVITEE_ALREADY_GROUP_MEMBER,
    GROUP_INVITEE_HAS_BEEN_BLOCKED_BY_GROUP,
    NOT_GROUP_OWNER_OR_MANAGER_TO_RECALL_GROUP_INVITATION,
    NOT_GROUP_OWNER_OR_MANAGER_TO_ACCESS_GROUP_INVITATION,
    NOT_GROUP_OWNER_TO_SEND_GROUP_INVITATION,
    NOT_GROUP_OWNER_OR_MANAGER_TO_SEND_GROUP_INVITATION,
    NOT_GROUP_MEMBER_TO_SEND_GROUP_INVITATION,
    RECALLING_GROUP_INVITATION_IS_DISABLED,
    SEND_GROUP_INVITATION_TO_GROUP_NOT_REQUIRE_INVITATION,
    RECALL_NON_PENDING_GROUP_INVITATION,

    // Conversation
    UPDATING_TYPING_STATUS_IS_DISABLED = 4000,
    UPDATING_READ_DATE_IS_DISABLED,
    UPDATING_READ_DATE_IS_DISABLED_BY_GROUP,
    UPDATING_READ_DATE_OF_NONEXISTENT_GROUP_CONVERSATION,
    NOT_GROUP_MEMBER_TO_UPDATE_READ_DATE_OF_GROUP_CONVERSATION,
    MOVING_READ_DATE_FORWARD_IS_DISABLED,

    // Message

    // Message - Send
    MESSAGE_RECIPIENT_NOT_ACTIVE = 5000,
    MESSAGE_SENDER_NOT_IN_CONTACTS_OR_BLOCKED,
    PRIVATE_MESSAGE_SENDER_HAS_BEEN_BLOCKED,
    GROUP_MESSAGE_SENDER_HAS_BEEN_BLOCKED,
    SEND_MESSAGE_TO_INACTIVE_GROUP,
    SEND_MESSAGE_TO_MUTED_GROUP,
    SEND_MESSAGE_TO_NONEXISTENT_GROUP,
    SENDING_MESSAGES_TO_ONESELF_IS_DISABLED,
    MUTED_GROUP_MEMBER_SEND_MESSAGE,
    GUESTS_HAVE_BEEN_MUTED,
    MESSAGE_IS_ILLEGAL,

    // Message - Update
    UPDATING_MESSAGE_BY_SENDER_IS_DISABLED = 5100,
    NOT_SENDER_TO_UPDATE_MESSAGE,
    UPDATE_MESSAGE_OF_NONEXISTENT_GROUP,
    UPDATING_GROUP_MESSAGE_BY_SENDER_IS_DISABLED,

    // Message - Recall
    RECALL_NONEXISTENT_MESSAGE = 5200,
    RECALLING_MESSAGE_IS_DISABLED,
    NOT_SENDER_TO_RECALL_MESSAGE,
    RECALL_MESSAGE_OF_NONEXISTENT_GROUP,
    MESSAGE_RECALL_TIMEOUT,

    // Message - Query
    NOT_GROUP_MEMBER_TO_QUERY_GROUP_MESSAGES = 5300,

    // Storage
    STORAGE_NOT_IMPLEMENTED = 6000,

    // Storage - Message attachment
    NOT_FRIEND_TO_UPLOAD_MESSAGE_ATTACHMENT_IN_PRIVATE_CONVERSATION = 6100,
    NOT_GROUP_MEMBER_TO_UPLOAD_MESSAGE_ATTACHMENT_IN_GROUP_CONVERSATION,
    NOT_UPLOADER_TO_SHARE_MESSAGE_ATTACHMENT,
    NOT_UPLOADER_OR_GROUP_MANAGER_TO_UNSHARE_MESSAGE_ATTACHMENT_IN_GROUP_CONVERSATION,
    NOT_UPLOADER_TO_UNSHARE_MESSAGE_ATTACHMENT_IN_PRIVATE_CONVERSATION,
    NOT_UPLOADER_OR_GROUP_MANAGER_TO_DELETE_MESSAGE_ATTACHMENT_IN_GROUP_CONVERSATION,
    NOT_UPLOADER_TO_DELETE_MESSAGE_ATTACHMENT_IN_PRIVATE_CONVERSATION,
    NOT_UPLOADER_OR_SHARED_WITH_USER_TO_DOWNLOAD_MESSAGE_ATTACHMENT,

    // Storage - Message attachment info
    NOT_FRIEND_TO_QUERY_MESSAGE_ATTACHMENT_INFO_IN_PRIVATE_CONVERSATION = 6130,
    NOT_GROUP_MEMBER_TO_QUERY_MESSAGE_ATTACHMENT_INFO_IN_GROUP_CONVERSATION
}

class ResponseStatusCode {

    static isSuccessCode(code: number | string | Code): boolean {
        if (typeof code === 'string') {
            code = parseInt(code);
        }
        return 1000 <= code && code < 1100;
    }

    static isErrorCode(code: number | string): boolean {
        return !this.isSuccessCode(code);
    }

}

export default Object.assign(ResponseStatusCode, Code);